Skip to content

Conversation

@benpicco
Copy link
Contributor

@benpicco benpicco commented Mar 4, 2019

The output of the net ping function is a bit terse.

Let's make it more Linux-like by reporting TTL, measuring round-trip-time and also display RSSI when available.

before:

uart:~$ net ping fe80::7b7a:342f:9d73:b482
Sent a ping to fe80::7b7a:342f:9d73:b482
Received echo reply from fe80::7b7a:342f:9d73:b482 to fe80::d07:d5e9:7c9:572d

after:

uart:~$ net ping fe80::7b7a:342f:9d73:b482
PING fe80::7b7a:342f:9d73:b482
8 bytes from fe80::7b7a:342f:9d73:b482 to fe80::7841:4946:59b8:3d9c: icmp_seq=0 ttl=64 rssi=-53 dBm time=6.65ms
8 bytes from fe80::7b7a:342f:9d73:b482 to fe80::7841:4946:59b8:3d9c: icmp_seq=1 ttl=64 rssi=-57 dBm time=6.59ms
8 bytes from fe80::7b7a:342f:9d73:b482 to fe80::7841:4946:59b8:3d9c: icmp_seq=2 ttl=64 rssi=-57 dBm time=6.56ms

@zephyrbot
Copy link

zephyrbot commented Mar 4, 2019

All checks are passing now.

Review history of this comment for details about previous failed status.
Note that some checks might have not completed yet.

@codecov-io
Copy link

codecov-io commented Mar 4, 2019

Codecov Report

Merging #14024 into master will decrease coverage by 0.07%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #14024      +/-   ##
==========================================
- Coverage   52.68%    52.6%   -0.08%     
==========================================
  Files         307      307              
  Lines       45473    45474       +1     
  Branches    10530    10530              
==========================================
- Hits        23956    23923      -33     
- Misses      16640    16668      +28     
- Partials     4877     4883       +6
Impacted Files Coverage Δ
subsys/net/ip/icmpv4.c 26.17% <0%> (-0.18%) ⬇️
subsys/net/ip/icmpv6.c 29.76% <0%> (-0.18%) ⬇️
subsys/net/lib/sockets/sockets_internal.h 28.57% <0%> (-71.43%) ⬇️
subsys/net/lib/sockets/sockets.c 46.81% <0%> (-2.21%) ⬇️
subsys/net/ip/tcp.c 55.95% <0%> (-1.53%) ⬇️
arch/posix/core/posix_core.c 90.9% <0%> (-1.02%) ⬇️
subsys/net/ip/net_context.c 58.5% <0%> (-0.27%) ⬇️
subsys/logging/log_core.c 37.2% <0%> (-0.26%) ⬇️
lib/os/printk.c 84.32% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d5d35d0...b2b5b93. Read the comment docs.

@benpicco benpicco force-pushed the fancy_ping branch 2 times, most recently from ad5ff11 to 53fd7d1 Compare March 4, 2019 10:56
pfalcon
pfalcon previously requested changes Mar 4, 2019
Copy link
Contributor

@pfalcon pfalcon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks very nice features, thanks!

But there're thing to elaborate in the patch still.

Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @benpicco, this looks really nice. Just few fixes and we are good to go.

@jukkar jukkar added this to the v1.14.0 milestone Mar 4, 2019
@benpicco benpicco requested a review from dbkinder as a code owner March 5, 2019 11:13
@benpicco benpicco force-pushed the fancy_ping branch 2 times, most recently from 7bd6c57 to 0481440 Compare March 5, 2019 12:08
Copy link
Contributor

@tbursztyka tbursztyka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split the 2nd commit in 3:

  • one adding timestamp as arbitrary data for icmpv4
  • one adding timestamp as arbitrary data for icmpv6
  • one improving shell

and apply all the comments as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where in icmpv4 rfc did you see such field for echo request?

That structure represents the echo req as specified from the RFC so you cannot modify it.

if you want to add data past the echo_req id/seq, you'll have to do it another way.

Copy link
Contributor Author

@benpicco benpicco Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea you are right. I've changed it to a u8_t data[] and let the application decide what arbitrary payload to put in there (if any).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not RFC compliant

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use net_pkt_ieee802154_rssi() (btw, rssi for 15.4 is u8_t as it is a value between 0 and 255, why the cast?)

Copy link
Contributor Author

@benpicco benpicco Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data coming from the nrf52 is a s8_t tough, and RSSI is usually given in negative dBm.
The only other use is currently in openthread.c where it is implicitly cast to s8_t again.
I think this is a bug in Zephyr's ieee802154 API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zephyr's 15.4 stack implements rssi as specified in 15.4 specs (8bits value from 0 to 255).
Ref: spec 2012 chapter 18.2.3.3

Though dbm would be indeed better (as it is the scale used also in BT and WiFi). I don't know why 15.4 came with its own definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, with two's complement it doesn't make a difference either way, higher values are better no matter if they are interpreted as signed or not.

If the standard says so I'll remove the cast.

@pfalcon
Copy link
Contributor

pfalcon commented Mar 5, 2019

@benpicco, Thanks for addressing the initial concerns raised.

@pfalcon pfalcon dismissed their stale review March 5, 2019 13:36

Initial concerns were addressed

@benpicco benpicco force-pushed the fancy_ping branch 4 times, most recently from 9391958 to e72271b Compare March 5, 2019 18:18
Copy link
Contributor

@dbkinder dbkinder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for doc change

@benpicco benpicco force-pushed the fancy_ping branch 2 times, most recently from 46b57d0 to c70e631 Compare March 5, 2019 18:30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

80 chars limit is passed here I guess

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved it to the next line

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit problematic, because the target (if implementing reply wrongly) might have replied without the arbitrary data (it is against RFC but there is no way to verify this until you actually reach this cb).

Instead just use net_pkt_read_be32_new(), that will tell you if there is an error, in which case you will return NET_DROP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, changed it to use net_pkt_read_be32_new() instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that won't be necessary then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though, at this stage of this function implementation, this logic is not wrong, it won't fly with time if one day the icmpv4_access is not a contiguous one anymore.

And in any case, never memcpy (or memmove etc..) by yourself. Alway use the net_pkt r/w api, because that API can tell you if it could r/w or not (it verifies that buffer does have the necessary space)

So after net_pkt_set_data() below, just do a net_pkt_write(pkt, data, data_size)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, changed it to net_pkt_write_new().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apply the same as for icmpv4.c

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

80 chars limit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved it to the next line

@tbursztyka
Copy link
Contributor

I guess you need to rebase and actually apply the fixups (git rebase -i for interactive mode)

@benpicco
Copy link
Contributor Author

benpicco commented Mar 6, 2019

I know, just thought it makes reviewing easier this way.
-> squashed.

benpicco added 2 commits April 8, 2019 18:31
Allow for including arbitrary data in net_icmpv4_send_echo_request()
that will be echoed verbatim by the receiver.

This allows to use ICMP echo for diagnostic use cases, e.g. by testing
packet framentation (large payload) or measuring round-trip-time.

Signed-off-by: Benjamin Valentin <[email protected]>
Allow for including arbitrary data in net_icmpv6_send_echo_request()
that will be echoed verbatim by the receiver.

This allows to use ICMP echo for diagnostic use cases, e.g. by testing
packet framentation (large payload) or measuring round-trip-time.

Signed-off-by: Benjamin Valentin <[email protected]>
@benpicco benpicco force-pushed the fancy_ping branch 2 times, most recently from 164d1ab to 5239d05 Compare April 8, 2019 16:39
@bublover
Copy link

Could you please add size parameter?
ping host -s 1470

@benpicco
Copy link
Contributor Author

benpicco commented Apr 10, 2019

@bublover Good idea, added it.

I'm not so happy about the VLA use, but k_malloc is only available when CONFIG_HEAP_MEM_POOL_SIZE is set - and that defaults to 0.

I've only tested the IPv6 version, but IPv4 should work the same.

Copy link

@bublover bublover Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @benpicco ,
About this payload, is it allocated from heap or thread stack or something else?
If from thread stack, is it possible to be overflowed with big size?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using VLAs is no good, please do it differently. One option could be to allocate enough net_buf's for a given size, and then pass that chain of net_buf's directly to net_icmpv6_send_echo_request() which can then send that data directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's allocated on the stack and yes that's bad.

I'm not sure how to do it with net_bufs though. Is there a way where I don't have to reserve dedicated memory for it using NET_BUF_POOL_DEFINE but instead can make use of some existing pool?

Another way would be to only enable the -s option if CONFIG_HEAP_MEM_POOL_SIZE is not 0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we seem to have lost proper API in net_pkt.h for allocating net_buf's.

Another option could be to use net_pkt_skip() and optionally with net_pkt_memset(). That way we could fill enough net_buf's with given byte value. This would be needed to be done inside net_icmpv6_send_echo_request() as the net_pkt is not exposed outside of that function.

So for example we could have something like net_icmpv6_send_echo_request(iface, dst, id, seq, len, value), and inside that func just do net_pkt_skip(pkt, len) followed by cursor setting and then net_pkt_memset(pkt, value). The cursor setting is a bit vague here as I am just brainstorming atm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking how net_pkt_skip() and net_pkt_memset() are implemented, it is probably enough just to call net_pkt_memset() which should allocate enough net_buf's to fill the packet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using VLAs is no good, please do it differently. One option could be to allocate enough net_buf's for a given size, and then pass that chain of net_buf's directly to net_icmpv6_send_echo_request() which can then send that data directly.

@jukkar
Copy link
Member

jukkar commented Apr 18, 2019

@benpicco could you rebase against latest master and re-submit without the size support, we can add that one later in separate PR.

@benpicco
Copy link
Contributor Author

@jukkar alright!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Print float data depends on some additional configs, otherwise, the time can not output correctly.

28 bytes from 192.168.1.1 to 192.168.1.100: icmp_seq=1 ttl=64 time=%.2f ms

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it's CONFIG_NEWLIB_LIBC_FLOAT_PRINTF and it only affects the formatting to two significant digits as %f is used elsewhere in that file.

Does it work for you now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also doesn't work with %f, can you please use %d instead as this is a universal network tool.

28 bytes from 192.168.1.1 to 192.168.1.100: icmp_seq=0 ttl=64 time=%f ms

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What target / config are you using?
When I build for nrf52840_pca10056, CONFIG_NEWLIB_LIBC_FLOAT_PRINTF is not set, yet %.2f is available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benpicco I'm using 96boards IVY5661, the board support patch(#10626) is not merged yet.

I tried to store time in a variable before output, It's very strange that printf works, but PR_SHELL not. It seems there is some issue with PR_SHELL.

    float time;
    time =  SYS_CLOCK_HW_CYCLES_TO_NS(cycles) / 1000000.f;
    printf("time: %f.\n", time);

    PR_SHELL(shell_for_ping, "%d bytes from %s to %s: icmp_seq=%d ttl=%d time=%f ms\n",
         ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - NET_ICMPH_LEN,
         net_sprint_ipv4_addr(&ip_hdr->src),
         net_sprint_ipv4_addr(&ip_hdr->dst),
         ntohs(icmp_echo->sequence),
         ip_hdr->ttl,
         time);

OUTPUT:
time: 4.418798.
28 bytes from 192.168.1.1 to 192.168.1.101: icmp_seq=0 ttl=64 time=%f ms

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this and noticed some issues. Using atoi() is not good as it returns 0 for invalid value. That is why the net-shell uses strtol() in other parts of the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, converted it to use strtol()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed that we cannot stop the ping after it is started. So if the user puts very high value here, the shell will be useless for a long period of time. I wonder if we could run the ping in separate thread or something like that in order to avoid this thing. We can do some limits later, no need to start to implement something like that here.

@jukkar jukkar changed the title Inet: ping: Improve the output of the ping function net: ping: Improve the output of the ping function Apr 24, 2019
@jukkar
Copy link
Member

jukkar commented Apr 25, 2019

We have now another problem. When compiling samples/net/sockets/echo_server in qemu_x86, I get following fault:

uart:~$ net ping 2001:db8::2
PING 2001:db8::2
***** Floating point unit not enabled

Current thread ID = 0x004016f8
eax: 0x00403566, ebx: 0x00406558, ecx: 0x00000000, edx: 0x00000000
esi: 0x0040354e, edi: 0x0040357a, ebp: 0x00406a88, esp: 0x00406a50
eflags: 0x00000206 cs: 0x0008
call trace:
eip: 0x00015911
     0x000123ac (0x123ac)
     0x00012abc (0x406558)
     0x0000de38 (0x406558)
     0x0000de97 (0x1)
     0x0000479c (0x40655c)
     0x0000475a (0x4016e0)
Fatal fault in thread 0x004016f8! Aborting.

After enabling CONFIG_FLOAT, the output print looks like this

8 bytes from 2001:db8::2 to 2001:db8::1: icmp_seq=0 ttl=64 time=26113401 ms
8 bytes from 2001:db8::2 to 2001:db8::1: icmp_seq=1 ttl=64 time=-1608035756 ms
8 bytes from 2001:db8::2 to 2001:db8::1: icmp_seq=2 ttl=64 time=669327703 ms

You need to add () when dividing like this

diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c
index bdb3e6ea4f..7a1836aef0 100644
--- a/subsys/net/ip/net_shell.c
+++ b/subsys/net/ip/net_shell.c
@@ -2696,7 +2696,7 @@ static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt,
 #ifndef CONFIG_NEWLIB_LIBC_FLOAT_PRINTF
                 (int)
 #endif
-                SYS_CLOCK_HW_CYCLES_TO_NS(cycles) / 1000000.f);
+                (SYS_CLOCK_HW_CYCLES_TO_NS(cycles) / 1000000.f));
        k_sem_give(&ping_timeout);
 
        net_pkt_unref(pkt);

For the float issue, add this change

index 7798d5a2f2..ca04d3e3c0 100644
--- a/subsys/net/ip/Kconfig
+++ b/subsys/net/ip/Kconfig
@@ -56,6 +56,7 @@ source "subsys/net/ip/Kconfig.ipv4"
 config NET_SHELL
        bool "Enable network shell utilities"
        select SHELL
+       select FLOAT
        help
          Activate shell module that provides network commands like
          ping to the console.

@pfalcon
Copy link
Contributor

pfalcon commented Apr 25, 2019

We have now another problem.
***** Floating point unit not enabled

So, I'd say we should keep avoiding floating point like we did before, and use fixed points calculations.

@benpicco
Copy link
Contributor Author

benpicco commented Apr 25, 2019

I've changed it so that it only uses float when CONFIG_FLOAT is set, otherwise it uses int and discards the sub-ms precision.

@easonxiang does this also remedy the problem on uwp5661?

@easonxiang
Copy link
Contributor

I've changed it so that it only uses float when CONFIG_FLOAT is set, otherwise it uses int and discards the sub-ms precision.

@easonxiang does this also remedy the problem on uwp5661?

@benpicco Yes, the int type works for me. I can not enable CONFIG_FLOAT as it depends on CPU_HAS_FPU, which is not available by uwp5661.
Thanks for your quickly response.

Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are almost there, just one tweak needed.

Report rtt, ttl and rssi if available.

Signed-off-by: Benjamin Valentin <[email protected]>
@jukkar jukkar merged commit 812b999 into zephyrproject-rtos:master Apr 26, 2019
@benpicco benpicco deleted the fancy_ping branch April 26, 2019 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants